package cn.jbolt.core.service;

import cn.jbolt.core.api.JBoltApiKit;
import cn.jbolt.core.base.JBoltMsg;
import cn.jbolt.core.common.enums.JBoltSystemLogTargetType;
import cn.jbolt.core.db.sql.Sql;
import cn.jbolt.core.enumutil.JBoltEnum;
import cn.jbolt.core.model.UserConfig;
import cn.jbolt.core.model.UserConfigKey;
import cn.jbolt.core.model.UserConfigValueType;
import cn.jbolt.core.service.base.JBoltBaseService;
import com.jfinal.kit.Okv;
import com.jfinal.kit.Ret;

import java.util.Date;
import java.util.List;
/**
 * 用户自身配置
 * @ClassName:  UserConfigService
 * @author: JFinal学院-小木 QQ：909854136
 * @date:   2019年9月25日
 */
public class JBoltUserConfigService extends JBoltBaseService<UserConfig> {
	protected UserConfig dao = new UserConfig().dao();
	@Override
	protected UserConfig dao() {
		return dao;
	}
	/**
	 * 获取用户配置
	 * @param userId
	 * @return
	 */
	public List<UserConfig> getAdminList(Long userId) {
		checkAndInit(userId);
		return getCommonList(Okv.by("user_id", userId));
	}

	/**
	 * 更新
	 * @param userId
	 * @param userConfig
	 * @return
	 */
	public Ret update(Long userId, UserConfig userConfig) {
		if (userConfig == null || notOk(userConfig.getId()) || notOk(userConfig.getConfigKey())
				|| notOk(userConfig.getConfigValue())) {
			return fail(JBoltMsg.PARAM_ERROR);
		}
		UserConfig db=findById(userConfig.getId());
		if(db==null){return fail(JBoltMsg.DATA_NOT_EXIST);}
		db.setConfigValue(userConfig.getConfigValue());
		boolean success=processUpdateConfig(db);
		return ret(success);
	}


	/**
	 * 检测和初始化配置
	 */
	public void checkAndInit(Long userId) {
		processDatasIfValueTypeIsNull(userId);
	}
	/**
	 * 处理valueType=null的组件
	 */
	private void processDatasIfValueTypeIsNull(Long userId) {
		Sql sql=selectSql().isNull("value_type").eq("user_id", userId);
		List<UserConfig> configs=find(sql.toSql());
		if(isOk(configs)) {
			//for(UserConfig config:configs) {
			//	//switch (config.getConfigKey()) {
			//	//
			//	//}
			//}
			batchUpdate(configs);
		}

	}
	/**
	 * 检查并初始化全局配置表数据
	 * @param userId
	 * @param configKey
	 */
	public void checkAndInitConfig(Long userId, String configKey) {
		boolean checkExist = checkUserExistConfig(userId, configKey);
		if (!checkExist) {
			UserConfig config = new UserConfig();
			config.setConfigKey(configKey);
			String value;
			switch (configKey) {

				//case JBoltGlobalConfigKey.JBOLT_LOGIN_NEST:
				//	config.setName("系统登录页面是否开启线条特效");
				//	value=JBoltGlobalConfigCache.me.getConfigValue(JBoltGlobalConfigKey.JBOLT_LOGIN_NEST);
				//	config.setConfigValue(isOk(value)?value:"true");
				//	config.setValueType(UserConfigType.TYPE_BOOLEAN);
				//	break;
			}
			config.setCreateTime(new Date());
			config.setUserId(userId);
			config.setUpdateTime(new Date());
			config.save();
		}

	}
	/**
	 * 检测用户相同配置是否存在
	 * @param userId
	 * @param configKey
	 * @return
	 */
	private boolean checkUserExistConfig(Long userId, String configKey) {
		UserConfig config=findFirst(Okv.by("user_id", userId).set("config_key",configKey));
		return config!=null;
	}
	/**
	 * 根据configKey获取全局配置
	 * @param configKey
	 * @return
	 */
	public UserConfig getByConfigKey(Long userId,String configKey) {
		return findFirst(Okv.by("config_key", configKey).set("user_id",userId));
	}
	/**
	 * 切换Boolean类型config
	 * @param userId
	 * @param id
	 * @return
	 */
	public Ret toggleBooleanConfig(Long userId, Long id) {
		UserConfig userConfig=findById(id);
		if(userConfig==null) {return fail(JBoltMsg.DATA_NOT_EXIST);}
		if(!userConfig.getValueType().equals(UserConfigValueType.TYPE_BOOLEAN)) {
			return fail("配置项的值必须为Boolean类型");
		}
		if(userConfig.getConfigValue().equals("true")) {
			userConfig.setConfigValue("false");
		}else {
			userConfig.setConfigValue("true");
		}
		boolean success=processUpdateConfig(userConfig);
		return success?successWithData(userConfig.getConfigKey()):fail();
	}
	/**
	 * 改变配置项值
	 * @param userId
	 * @param id
	 * @param value
	 * @return
	 */
	public Ret changeStringValue(Long userId, Long id, String value) {
		if(notOk(value)||notOk(id)) {return fail(JBoltMsg.PARAM_ERROR);}
		UserConfig userConfig=findById(id);
		if(userConfig==null) {return fail(JBoltMsg.DATA_NOT_EXIST);}
		if(!userConfig.getValueType().equals(UserConfigValueType.TYPE_STRING)) {
			return fail("配置项的值必须为String类型");
		}
		userConfig.setConfigValue(value);
		boolean success=processUpdateConfig(userConfig);
		return ret(success);
	}
	/**
	 * 更新操作 附带处理日志和缓存
	 * @param userConfig
	 * @return
	 */
	private boolean processUpdateConfig(UserConfig userConfig) {
		userConfig.setUpdateTime(new Date());
		boolean success=userConfig.update();
		if(success) {
			//增加日志
			addUpdateSystemLog(userConfig.getId(), userConfig.getUserId(), userConfig.getName()+"为:["+userConfig.getConfigValue()+"]");
		}
		return success;
	}
	@Override
	protected int systemLogTargetType() {
		return JBoltSystemLogTargetType.USER_CONFIG.getValue();
	}

	public Ret changeUserConfig(Long userId, String configKey,String configValue) {
		UserConfig userConfig = getByConfigKey(userId,configKey);
		if(userConfig == null){
			userConfig = new UserConfig();
			userConfig.setUserId(JBoltApiKit.getApiUserIdToLong());
			userConfig.setConfigKey(configKey);
			userConfig.setConfigValue(configValue);
			processValueTypeAndName(userConfig);
			boolean success = userConfig.save();
			return ret(success);
		}
		userConfig.setConfigValue(configValue);
		boolean success = userConfig.update();
		return ret(success);
	}

	private void processValueTypeAndName(UserConfig userConfig) {
		boolean success = processInnerConfigKey(userConfig);
		if(!success){
			processExtendUserConfig(userConfig);
		}

	}

	private boolean processInnerConfigKey(UserConfig userConfig) {
		UserConfigKey userConfigKey = JBoltEnum.getEnumObjectByValue(UserConfigKey.class,userConfig.getConfigKey());
		if(userConfig == null || userConfigKey == null){
			return false;
		}
		boolean success = true;
		switch (userConfigKey){
			case USER_ADMIN_THEME:
				userConfig.setValueType(UserConfigValueType.TYPE_STRING);
				userConfig.setName("用户自定义系统主题样式");
				break;
			default:
				success = false;
				break;
		}
		return success;
	}

	protected void processExtendUserConfig(UserConfig userConfig){
		//TODO 需要覆写
	}
}
